package com.springcloudali.ms;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * <h1>8位技术专家全程教学实战，全面覆盖Java进阶知识体系。<br/><br/><a href="https://u.geekbang.org/subject/java4th/1001148?source=app_share">极客训练营地址：https://u.geekbang.org/subject/java4th/1001148?source=app_share</a></h1><br/><h1><a href="https://gitee.com/ylimhhmily/SpringCloudAlibabaTutorial">极客案例代码地址：https://gitee.com/ylimhhmily/SpringCloudAlibabaTutorial</a></h1><br/><h1><a href="https://time.geekbang.org/column/intro/100312101">Dubbo 源码剖析与实战：https://time.geekbang.org/column/intro/100312101</a></h1>
 *
 * @author hmilyylimh
 * ^_^
 * @version 0.0.1
 * ^_^
 * @date 2023-05-12
 */
@Component
public class CostGatewayFilterFactory extends AbstractGatewayFilterFactory<CostGatewayFilterFactory.ValueConfig> {

    public CostGatewayFilterFactory() {
        super(ValueConfig.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("status");
    }

    @Override
    public GatewayFilter apply(ValueConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange,
                                     GatewayFilterChain chain) {
                // config = ON/OFF
                if (!"ON".equalsIgnoreCase(config.getStatus())) {
                    return chain.filter(exchange);
                }

                // 处理请求之前，这里可以干点事情
                // 记录开始时间
                exchange.getAttributes().put("START_TIME", System.currentTimeMillis());

                return chain.filter(exchange).then(Mono.fromRunnable(new Runnable() {
                    @Override
                    public void run() {
                        // 处理请求之后，这里也可以干点事情
                        Long startTime = exchange.getAttribute("START_TIME");
                        if(startTime != null){
                            long endTime = System.currentTimeMillis();
                            long cost = endTime - startTime;

                            System.out.println("请求地址: " + exchange.getRequest().getURI()
                             + " 耗时为：" + cost + " 毫秒。");
                        }
                    }
                }));
            }
        };
    }

    public static class ValueConfig {

        private String status;

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }
    }
}